package com.xbongbong.paas.filter;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.xbongbong.paas.connection.enums.OpenAppEnum;
import com.xbongbong.paas.connection.service.IOpenAppService;
import com.xbongbong.paas.connection.service.OpenAppFactory;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.paas.wrapper.RequestWrapper;
import com.xbongbong.paas.wrapper.ResponseWrapper;
import com.xbongbong.pro.constant.XbbProConstant;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Resource;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap;

/**
 *
 * 创建时间 2020/3/30 9:55 AM
 * 修改时间 2020/3/30 9:55 AM
 * @author chy
 */
@WebFilter(urlPatterns = {XbbProConstant.API_ROOT_PREFIX + "/connection/*"}, filterName = "connectionFilter")
public class ConnectionFilter implements Filter {
    private static  final Logger LOG = LoggerFactory.getLogger(ConnectionFilter.class);
    @Resource
    private OpenAppFactory openAppFactory;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        ServletOutputStream out = response.getOutputStream();
        RequestWrapper requestWrapper = new RequestWrapper(httpRequest);
        byte[] requestWrapperBody = requestWrapper.getBody();
        String requestWrapperString = new String(requestWrapperBody, StandardCharsets.UTF_8);
        //确保json字符串序列化后保持字段顺序不变
        LinkedHashMap json = null;
        try {
            json = JSON.parseObject(requestWrapperString, LinkedHashMap.class, Feature.OrderedField);
        } catch (Exception e) {
            //在下面null逻辑中
        }
        LOG.info("--------json-------:" + json);
        if (json == null) {
            // 错误返回
            errorReturn(out, new XbbException(SystemErrorCodeEnum.API_ERROR_100002));
            return;
        }
        JSONObject requestJsonObject = new JSONObject(true);
        requestJsonObject.putAll(json);

        //将header中的openAppId置入body中
        Integer openAppId = StringUtil.toInt(httpRequest.getHeader("openAppId"), null);
        String url = httpRequest.getRequestURI();
        LOG.info("url:" + url);
        OpenAppEnum openAppEnum = OpenAppEnum.getByCallBackUrl(url);
        LOG.info("openAppEnum:" + openAppEnum);
        if (openAppEnum != null) {
            try {
                IOpenAppService openAppService = openAppFactory.openAppFactory(openAppEnum);
                openAppService.requestCheck(httpRequest, requestJsonObject);
            } catch (XbbException e) {
                errorReturn(out, e);
                return;
            }
        }
        requestJsonObject.put("openAppId", openAppId);
        requestWrapper.setBody(requestJsonObject.toJSONString());

        ResponseWrapper responseWrapper = new ResponseWrapper(httpResponse);
        chain.doFilter(requestWrapper, responseWrapper);
    }


    @Override
    public void destroy() {

    }

    /**
     * 错误 response 返回
     * @param out ServletOutputStream response输出流
     * @param xe 业务异常
     * @throws IOException 有可能抛出IO异常
     */
    private void errorReturn(ServletOutputStream out, XbbException xe) throws IOException {
        XbbResponse verifyError = new XbbResponse(xe);
        out.write(JSON.toJSONString(verifyError).getBytes("UTF-8"));
        out.flush();
    }
}
